package com.my.study.structures.queue;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Carlos
 * @version 1.0
 * @Description 数组 -> 普通队列
 * <p>
 * 队列满：(rear + 1)  % maxSize == front;
 * 队列空：rear == front;
 * 队列有效数据：(rear + maxSize - front) % maxSize
 * @date 2021/6/7 21:45
 **/
@Slf4j(topic = "c.CircleArrayQueue")
public class CircleArrayQueue {
    /**
     * 最大容量
     */
    private int maxSize;

    /**
     * 队列头:指向队列第一个元素
     */
    private int front;

    /**
     * 队列尾：指向队列最后一个元素的后一个位置
     */
    private int rear;

    private int[] arr;

    public CircleArrayQueue() {
        this(10);
    }

    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
    }

    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    public boolean isEmpty() {
        return rear == front;
    }

    public void addQueue(int n) {
        if (isFull()) {
            log.debug("队列已满");
            return;
        }
        arr[rear] = n;
        // 将rear后移，考虑取模
        rear = (rear + 1) % maxSize;
    }

    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空，不能获取到数据");
        }

        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }

    public void showQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空，不能获取到数据");
        }

        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d] = %d\n", i % maxSize, arr[i % maxSize]);
        }
    }

    public int headQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空，不能获取到数据");
        }
        return arr[front];
    }

    /**
     * 队列有效数据数量
     *
     * @return
     */
    public int size() {
        return (rear + maxSize - front) % maxSize;
    }

}
